package com.dyrj.ysk.util;

import com.dyrj.ysk.constants.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;

import java.io.*;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.UUID;

/**
 * 将私钥文件，公钥文件转换成公私钥内容工具类
 * @author 吴侠志  2020/5/14
 * @version 1.0
 */
@Slf4j
public class CertUtil {
    private static PrivateKey getPriKey(KeyStore keyStore,String password){
        try {
            Enumeration<String> aliasenum  = keyStore.aliases();
            if (aliasenum.hasMoreElements()) {
                String keyAlias = aliasenum.nextElement();
                if (keyStore.isKeyEntry(keyAlias)) {
                    PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias,password.toCharArray());
                    return privateKey;
                }
            }
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static PublicKey getPubKey(KeyStore keyStore){
        try {
            Enumeration<String> aliasenum = keyStore.aliases();
            String keyAlias = null;
            if (aliasenum.hasMoreElements()) {
                keyAlias = aliasenum.nextElement();
                if (keyStore.isKeyEntry(keyAlias)) {
                    X509Certificate  x509Certificate = (X509Certificate) keyStore.getCertificate(keyAlias);
                    PublicKey publicKey = x509Certificate.getPublicKey();
                    return publicKey;
                }
            }
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过流的形式加载证书
     * @param fis
     * @param password
     * @return
     */
    private static KeyStore loadKeyStore(InputStream fis, String password){
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            char[] nPassword = password.toCharArray();
            if (null != keyStore) {
                keyStore.load(fis, nPassword);
            }
            return keyStore;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(null!=fis) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }




    /**
     * 通过路径加载证书
     * @param pfxkeyfile
     * @param password
     * @return
     */
    private static KeyStore loadKeyStore(String pfxkeyfile,String password){
        System.out.println("加载签名证书==>" + pfxkeyfile);
        FileInputStream fis = null;
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            File file = new File(pfxkeyfile);
            fis = new FileInputStream(file);
            char[] nPassword = password.toCharArray();
            if (null != keyStore) {
                keyStore.load(fis, nPassword);
            }
            return keyStore;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(null!=fis) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 通过路径方式获取证书
     * @param pubkeyfile
     * @return
     */
    private static PublicKey loadPubkey(String pubkeyfile){
        System.out.println("加载验签证书==>" + pubkeyfile);
        CertificateFactory cf = null;
        FileInputStream in = null;
        try {
            cf = CertificateFactory.getInstance("X.509");
            in = new FileInputStream(pubkeyfile);
            X509Certificate validateCert = (X509Certificate) cf.generateCertificate(in);
            return validateCert.getPublicKey();
        }catch (CertificateException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过流方式获取证书
     * @param in
     * @return
     */
    private static PublicKey loadPubkey(InputStream in){
        CertificateFactory cf = null;
        try {
            cf = CertificateFactory.getInstance("X.509");
            X509Certificate validateCert = (X509Certificate) cf.generateCertificate(in);
            return validateCert.getPublicKey();
        }catch (CertificateException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 通过路径获取公钥证书内容
     * @param pubKeyFile
     * @return
     */
    public static String getPubKeyStr(String pubKeyFile){
        PublicKey publicKey1 = loadPubkey(pubKeyFile);
        return Base64.encodeBase64String(publicKey1.getEncoded());
    }

    /**
     * 通过流获取公钥证书内容
     * @param inputStream
     * @return
     */
    public static String getPubKeyStr(InputStream inputStream){
        PublicKey publicKey1 = loadPubkey(inputStream);
        return Base64.encodeBase64String(publicKey1.getEncoded());
    }

    /**
     * 通过路径获取私钥证书-私钥内容
     * @param priKeyFile
     * @param pwd
     * @return
     */
    public static String getPriKeyStr(String priKeyFile,String pwd){
        KeyStore keyStore = loadKeyStore(priKeyFile,pwd);
        PrivateKey privateKey = getPriKey(keyStore,pwd);
        return Base64.encodeBase64String(privateKey.getEncoded());
    }

    /**
     * 通过流获取私钥证书-私钥内容
     * @param
     * @param pwd
     * @return
     */
    public static String getPriKeyStr(InputStream inputStream,String pwd){
        KeyStore keyStore = loadKeyStore(inputStream,pwd);
        PrivateKey privateKey = getPriKey(keyStore,pwd);
        return Base64.encodeBase64String(privateKey.getEncoded());
    }

    /**
     * 通过流获取私钥证书-私钥内容
     * @param
     * @param pwd
     * @return
     */
    public static PrivateKey getPriKey(InputStream inputStream,String pwd){
        KeyStore keyStore = loadKeyStore(inputStream,pwd);
        PrivateKey privateKey = getPriKey(keyStore,pwd);
        return privateKey;
    }


    /**
     * 获取私钥证书-公钥内容
     * @param priKeyFile
     * @param pwd
     * @return
     */
    public static String getPubKeyStr(String priKeyFile,String pwd){
        KeyStore keyStore = loadKeyStore(priKeyFile,pwd);
        PublicKey priPublicKey = getPubKey(keyStore);
        return Base64.encodeBase64String(priPublicKey.getEncoded());
    }

    public static void main(String[] args) {
        File pfx=new File("D:\\IdeaProjects\\pigframe\\conf\\2000804756@65.pfx");
        String passwd="1";
        String priKey=CertUtil.getPriKeyStr(pfx.getAbsolutePath(),passwd);
        System.out.println(priKey);

        File cert=new File("D:\\IdeaProjects\\pigframe\\conf\\open.cer");
        String pubKey= CertUtil.getPubKeyStr(cert.getAbsolutePath());
        System.out.println(pubKey);

    }
}
